package Thread;

import java.util.concurrent.TimeUnit;

/**
 * @Author: 逸尘风清
 * @Date: 2021/4/26
 * @Time: 20:42
 * 描述：
 */
public class Volatile {
    private boolean running = true;
    // private volatile boolean running = true;

    public void m(){
        System.out.println("m start");
        while (running){

        }
        System.out.println("m end");
    }

    public static void main(String[] args) {
        Volatile aVolatile = new Volatile();
        new Thread(aVolatile::m, "m").start();
        // 等同于上面的写法 , 上面使用的是Lambda表达式
        // new Thread(new Runnable() {
        //     @Override
        //     public void run() {
        //         aVolatile.m();
        //     }
        // });

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        aVolatile.running = false;
    }

    /**
     * 以上程序运行结果：
     * 没有开启 volatile ，  输出 m start 然后一直在while循环体中执行
     * 开启 volatile ，  输出 m start ， 2秒后输出 m end。
     * 原因：volatile是可变易变的意思，开启后说明这个属性是可变的，那么系统就会时时监控它的变化
     * 作用：
     * 1.保证线程可见性
     * JAVA是有多内存，所有的线程是共享这些内存的。 但是每个线程又有自己独立的工作内存空间。假设有两个线程，他们都需要调用共享内存里面的某个变量。这两个线程会将这个变量copy一份到自己空间。那么当其中一个线程对这个变量值改变的时候，另外一个线程是无法知晓，它什么时候会被写回到共享内存里面，无法立马监听到值的改变。
     * 当开启volatile之后，就能实时相互监听到值的改变
     * 是根据cpu缓存一致性来实现的
     * 2.禁止指令重排序
     * 见Volatile2详解
     */
}
